import time

from uiautomator2 import Device

from le_engine.base import LittleEmpire
from le_engine.cage_utils import CageUtils
from le_engine.config import CommonConfig, IconName
from simulators.mumu_control import MuMuControl
from utils.logger import log
from utils.utils import account_config


class TaskDigMojo:

    def __init__(self, le: LittleEmpire, event=None, sim_index=None, forever=True):
        self.le = le
        self.client: Device = self.le.get_client()
        self.forever = forever

        self.re_try_times = 0
        self.event = event

        self.cage = CageUtils(le, event=event)

        self.sim_index = sim_index
        self.sim = None if sim_index is None else MuMuControl()

    def get_lineup(self, cage_index, default="挖矿"):
        lineup_config = account_config().get("lineup_config", {})
        lineup = lineup_config.get(f"牢笼{cage_index + 1}", default)
        if lineup:
            value = lineup
        else:
            value = default
        log.info(f"牢笼{cage_index + 1} 选择阵容：{value}", extra={"pk": self.le.pk})
        return value

    def attack(self, index):
        self.cage.next_page()
        muggle_list = self.client(textContains="麻瓜")

        re_try = 0
        while not muggle_list.exists and re_try < 8:
            time.sleep(4)
            self.cage.next_page()
            muggle_list = self.client(textContains="麻瓜")
            re_try += 1

        if not muggle_list.exists:
            return True, self.cage.Digging

        for muggle in muggle_list:

            log.info(f"选中：{muggle.get_text()}", extra={"pk": self.le.pk})
            muggle.click()
            if self.cage.attack():
                if self.le.im.click_image(CommonConfig.img_path(IconName.read), max_retries=5):
                    if self.client(text="读取阵型").wait(timeout=CommonConfig.n_t_o):
                        self.client(text=self.get_lineup(cage_index=index)).click_exists(timeout=CommonConfig.n_t_o)
                        if self.le.im.click_image(CommonConfig.img_path(IconName.confirm), max_retries=5):
                            if self.client(text="你想抓谁做奴隶").wait(timeout=CommonConfig.net_t_o):
                                return True, self.cage.Digging

                            if self.client(text="你的部队正在行军赶路呢").wait(timeout=CommonConfig.n_t_o):
                                self.client.click(0.624, 0.432)
                                self.le.im.click_image(CommonConfig.img_path(IconName.close), max_retries=2)
                                continue

                            if self.client(text="你已攻占过该君主，24小时后才能再次攻占").wait(timeout=CommonConfig.n_t_o):
                                self.client.click(0.826, 0.105)
                                self.le.im.click_image(CommonConfig.img_path(IconName.close), max_retries=2)
                                continue
        self.client(text="换一批").click_exists(timeout=CommonConfig.n_t_o)
        return False, ""

    def fill_lineup(self, index):
        if account_config().get("s_lineup", 0) == 1:
            # 补充阵容
            log.info("补充阵容", extra={"pk": self.le.pk})
            time.sleep(2)
            self.le.client.click(0.5, 0.5)
            if self.le.im.click_image(CommonConfig.img_path(IconName.cage_check)):
                if self.client(text="信件").wait(timeout=CommonConfig.n_t_o):
                    log.info("游戏BUG，需要重启游戏", extra={"pk": self.le.pk})
                    return True, self.cage.Restart
                if self.le.im.click_image(CommonConfig.img_path(IconName.s_lineup), max_retries=10):
                    if self.le.im.click_image(CommonConfig.img_path(IconName.read), max_retries=5):
                        if self.client(text="读取阵型").wait(timeout=CommonConfig.n_t_o):
                            self.client(text=self.get_lineup(cage_index=index)).click_exists(timeout=CommonConfig.n_t_o)
                            if self.le.im.click_image(CommonConfig.img_path(IconName.confirm), max_retries=5):
                                if self.le.im.click_image(CommonConfig.img_path(IconName.cage_back), max_retries=2):
                                    log.info("补充阵容成功", extra={"pk": self.le.pk})

                                    if not self.le.im.find_image(CommonConfig.img_path(IconName.main_castle), max_retries=3):
                                        self.le.find_main_castle()
                                        self.client.click(0.5, 0.5)
                                        self.sim.android_back(index=self.sim_index)
                                        self.client(text="开始游戏").click_exists(timeout=CommonConfig.n_t_o)

                                    if self.le.im.find_image(CommonConfig.img_path(IconName.main_castle), max_retries=5):
                                        self.le.find_cage()
                                        for i in range(index+1):
                                            self.client.click(*self.cage.cage_position[i])
                                            self.sim.android_back(index=self.sim_index)
                                            self.client(text="开始游戏").click_exists(timeout=CommonConfig.n_t_o)
                                        return False, None
                                    return True, self.cage.Restart
            log.info("补充阵容失败", extra={"pk": self.le.pk})
            return False, None
        return False, None

    def dig(self, index=0) -> (bool, str):
        time.sleep(1)
        if self.event and self.event.is_set():
            log.info(f"已停止挖矿", extra={"pk": self.le.pk})
            return False, None
        ok, msg = self.cage.enter_cage(index)
        if not ok and msg == self.cage.Error:
            self.le.im.click_image(CommonConfig.img_path(IconName.xlc_close))
            return True, self.cage.Digging

        if not ok and msg in self.cage.Captured:
            self.le.im.click_image(CommonConfig.img_path(IconName.paiqian), max_retries=2)
            if self.le.im.click_image(CommonConfig.img_path(IconName.tanxian), max_retries=2):
                ok, msg = self.fill_lineup(index)
                if ok:
                    return ok, msg
            return True, self.cage.Digging

        if not ok and msg in self.cage.Digging:
            self.sim.android_back(self.sim_index)
            self.client(text="开始游戏").click_exists(timeout=CommonConfig.n_t_o)
            return True, self.cage.Digging

        attacked, attack_msg, re_try = False, "", 0
        while not attacked and re_try <= 5:
            attacked, attack_msg = self.attack(index)
            re_try = re_try + 1

        self.le.im.click_image(CommonConfig.img_path(IconName.xlc_close), max_retries=2)
        return True, attack_msg

    def start(self) -> (bool, str):
        if self.forever:
            cond = True
        else:
            cond = self.re_try_times <= 5

        while cond:

            if self.event and self.event.is_set():
                log.info("已停止挖矿", extra={"pk": self.le.pk})
                return False, None

            if not self.le.inter_game(forever=self.forever):
                self.re_try_times += 1
                continue
            self.cage.focus_cage()

            mojo_list = self.le.im.find_all_image(CommonConfig.img_path(IconName.mojo))
            pre_pos = None
            for mojo in mojo_list:
                if pre_pos is not None:
                    if abs(mojo[0] - pre_pos[0]) + abs(mojo[1] - pre_pos[1]) < 10:
                        log.info("已收获，跳过", extra={"pk": self.le.pk})
                        continue
                log.info(f"收获:{mojo}", extra={"pk": self.le.pk})
                self.client.click(*mojo)
                time.sleep(1)
                if self.client(text="收获统计").wait(timeout=CommonConfig.net_t_o):
                    self.le.im.click_image(CommonConfig.img_path(IconName.close), max_retries=2)
                pre_pos = mojo

            if pre_pos:
                continue

            cap = 0
            cage_num = len(account_config().get("lineup_config"))

            for index in range(cage_num):
                try:
                    ok, msg = self.dig(index)
                    if msg == self.cage.Restart and index != len(self.cage.cage_position) - 1:
                        break

                    if ok and msg == self.cage.Digging:
                        cap += 1

                except Exception as e:
                    log.error(str(e))
                    self.re_try_times += 1

            if cap == cage_num:
                dig_w_t = account_config().get("dig_w_t", 30)
                log.info(f"所有牢笼都在挖矿中，等待{dig_w_t}s后检查状态", extra={"pk": self.le.pk})
                time.sleep(dig_w_t)

            # self.cage.wait_attack()
        return True, None